module easyriscv(
	clk,
	rst,

	timer_int,
	external_int,

	iwishbone_data_i,
	iwishbone_ack_i,
	iwishbone_addr_o,
	iwishbone_data_o,
	iwishbone_we_o,
	iwishbone_sel_o,
	iwishbone_stb_o,
	iwishbone_cyc_o,
	
	dwishbone_data_i,
	dwishbone_ack_i,
	dwishbone_addr_o,
	dwishbone_data_o,
	dwishbone_we_o,
	dwishbone_sel_o,
	dwishbone_stb_o,
	dwishbone_cyc_o
);

input clk;
input rst;

input timer_int;
input [4:0] external_int;

input [31:0] iwishbone_data_i;
input iwishbone_ack_i;
output [31:0] iwishbone_addr_o;
output [31:0] iwishbone_data_o;
output iwishbone_we_o;
output [3:0] iwishbone_sel_o;
output iwishbone_stb_o;
output iwishbone_cyc_o;
	
input [31:0] dwishbone_data_i;
input dwishbone_ack_i;
output [31:0] dwishbone_addr_o;
output [31:0] dwishbone_data_o;
output dwishbone_we_o;
output [3:0] dwishbone_sel_o;
output dwishbone_stb_o;
output dwishbone_cyc_o;
//wire
//pc
wire [2:0] s;
wire c_pc;
wire pc_mux;
wire [31:0] pc_data;
wire mem_en;
wire [31:0] mem_addr;
wire [31:0] data_pc;
wire ins_en;

//mem
wire [31:0] ins_instruction;
wire stallreq_from_m;
//ins
wire c_ins;
wire [31:0] ins_pc;
wire [31:0] id_instruction;
wire id_en;
wire do_en;

//id
wire J_en;
wire [31:0] J_data;
wire [31:0] J_data1;
wire [31:0] J_addr;
wire [31:0] J_addrp;
wire [2:0] J_how;

wire alu_en;
wire [4:0] alu_reg_addr;
wire [11:0] alu_csr_addr;
wire [31:0] alu_data;
wire [31:0] alu_data1;
wire [31:0] alu_mcause;
wire [31:0] alu_mtval;
wire [1:0] alu_where;
wire [7:0] alu_how;

wire [4:0] reg_addr;
wire [4:0] reg1_addr;
wire [31:0] reg_data;
wire [31:0] reg1_data;

wire [11:0] csr_addr;
wire [31:0] csr_data;
wire [31:0] csr_mtvec;
wire [31:0] csr_mepc;
wire [31:0] csr_mie;
wire [31:0] csr_mip;
wire [31:0] csr_mstatus;

wire id_c_int;

//regs
wire reg_en_write;
wire [4:0] reg_write_addr;
wire [31:0] reg_write_data;

//csrs
wire csr_en;
wire [11:0] csr_addr1;
wire [31:0] csr_data1;
wire csr_int_en;
wire [31:0] csr_mepc1;
wire [31:0] csr_mcause;
wire [31:0] csr_mtval;
wire [31:0] csr_mstatus1;


//do
wire c_do;

wire do_en1;
wire [4:0] do_reg_addr;
wire [11:0] do_csr_addr;
wire [31:0] do_data;
wire [31:0] do_data1;
wire [31:0] do_mcause;
wire [31:0] do_mtval;
wire [1:0] do_where;
wire [7:0] do_how;

//alu
wire alu_mem_en;
wire alu_mem_rw;
wire [31:0] alu_mem_addr;
wire [31:0] alu_mem_data_r;
wire [31:0] alu_mem_data_w;
wire [3:0] alu_mem_byte_en;

//ctrl
wire stallreq_from_m1;

//clint
wire external_int_o;
wire [31:0] clint_data_o;

//mod
PC_mod PC(
	.clk(clk),
	.rst(rst),

	.pc_en_i(1'b1),
	.s_pc_i(s),
	.c_pc_i(c_pc),

	.pc_mux_i(pc_mux),
	.pc_data_i(pc_data),
	
	.mem_en_o(mem_en),
	.mem_addr_o(mem_addr),
	.pc_o(data_pc),
	
	.ins_en_o(ins_en)
);

wishbone_bus_if mem(

	.clk(clk),
	.rst(rst),
	
//??????ctrl
	.stall_i(s[0]),
	.flush_i(pc_mux),
	
//CPU???????
	.cpu_ce_i(mem_en),
	.cpu_data_i(32'b0),
	.cpu_addr_i(mem_addr),
	.cpu_we_i(1'b0),
	.cpu_sel_i(4'hf),
	.cpu_data_o(ins_instruction),
	
//Wishbone?????
	.wishbone_data_i(iwishbone_data_i),
	.wishbone_ack_i(iwishbone_ack_i),
	.wishbone_addr_o(iwishbone_addr_o),
	.wishbone_data_o(iwishbone_data_o),
	.wishbone_we_o(iwishbone_we_o),
	.wishbone_sel_o(iwishbone_sel_o),
	.wishbone_stb_o(iwishbone_stb_o),
	.wishbone_cyc_o(iwishbone_cyc_o),

	.stallreq(stallreq_from_m)   
	
);

ins_mod ins(
	.clk(clk),
	.rst(rst),

	.ins_en_i(ins_en),
	.c_ins_i(c_ins ),
	.s_ins_i(s),
	.c_int_i(pc_mux),

	.PC_i(data_pc),
	.mem_data_i(ins_instruction),

	.PC_o(ins_pc),
	.mem_data_o(id_instruction),

	.id_en_o(id_en),
	.do_en_o(do_en)
);

clint_mod clint(
	.rst(rst),

	.clint_int_i(external_int),
	
	.external_int_o(external_int_o),
	.clint_data_o(clint_data_o)
);

id_mod id(
	.rst(rst),

//杈撳叆浣胯兘
	.id_en_i(id_en),

//杈撳叆淇″彿
	.PC_i(ins_pc),
	.mem_data_i(id_instruction),

//鍒ゆ柇杞ЩJ妯″潡
	.J_en_o(J_en),
	.J_data_o(J_data),
	.J_data1_o(J_data1),
	.J_addr_o(J_addr),
	.J_addrp_o(J_addrp),
	.J_how_o(J_how),

//鎺у埗alu妯″潡
	.alu_en_o(alu_en),
	.alu_reg_addr_o(alu_reg_addr),
	.alu_csr_addr_o(alu_csr_addr),
	.alu_data_o(alu_data),
	.alu_data1_o(alu_data1),
	.alu_mcause_o(alu_mcause),
	.alu_mtval_o(alu_mtval),
	.alu_where_o(alu_where),
	.alu_how_o(alu_how),


//鎺у埗regs妯″潡
	.reg_addr_o(reg_addr),
	.reg1_addr_o(reg1_addr),
	.reg_data_i(reg_data),
	.reg1_data_i(reg1_data),

//鎺у埗csrs妯″潡
	.csr_addr_o(csr_addr),
	.csr_data_i(csr_data),
	.csr_mtvec_i(csr_mtvec),
	.csr_mepc_i(csr_mepc),
	.csr_mie_i(csr_mie),
	.csr_mip_i(csr_mip),
	.csr_mstatus_i(csr_mstatus),

//鏆傚仠int妯″潡
	.c_int_o(),


//寮傚父杈撳叆
	.I_a_m_i(1'b0),
	.I_a_f_i(1'b0),
	.L_a_m_i(1'b0),
	.L_a_f_i(1'b0),
	.S_a_m_i(1'b0),
	.S_a_f_i(1'b0),

	.clint_data_i(clint_data_o)
);

regs_mod regs(
	.rst(rst),
	.clk(clk),
	.reg_read_addr(reg_addr),
	.reg_read_addr1(reg1_addr),
	.reg_read_data(reg_data),
	.reg_read_data1(reg1_data),
	.reg_write_addr(reg_write_addr),
	.reg_write_data(reg_write_data),
	.reg_en_write(reg_en_write)
);

J_mod J(
	.rst(rst),

	.J_en_i(J_en),
	.J_data_i(J_data),
	.J_data1_i(J_data1),
	.J_addr_i(J_addr),
	.J_addrp_i(J_addrp),
	.J_how_i(J_how),

	.J_mux_o(pc_mux),
	.J_PC_o(pc_data)
);

csrs_mod csrs(
	.rst(rst),
	.clk(clk),
//id璇诲彇妯″潡
	.csr_addr_i(csr_addr),
	.csr_data_o(csr_data),
	.csr_mtvec_o(csr_mtvec),
	.csr_mepc_o(csr_mepc),
	.csr_mie_o(csr_mie),
	.csr_mip_o(csr_mip),
	.csr_mstatus_o(csr_mstatus),

//csr鐘舵€佸瘎瀛樺櫒澶勭悊鎺ュ彛
	.csr_en_i(csr_en),
	.csr_addr1_i(csr_addr1),
	.csr_data_i(csr_data1),

//涓柇瀹炵幇鎺ュ彛
	.csr_int_en_i(csr_int_en),
	.csr_mepc_i(csr_mepc1),
	.csr_mcause_i(csr_mcause),
	.csr_mtval_i(csr_mtval),
	.csr_mstatus_i(csr_mstatus1),
	
	.timer_int(timer_int),
	.external_int(external_int_o)
);

do_mod u_do(
	.clk(clk),
	.rst(rst),

	.do_en_i(do_en),
	.c_do_i(c_do),
	.s_do_i(s),

	.do_alu_en_i(alu_en),
	.do_reg_addr_i(alu_reg_addr),
	.do_csr_addr_i(alu_csr_addr),
	.do_data_i(alu_data),
	.do_data1_i(alu_data1),
	.do_mcause_i(alu_mcause),
	.do_mtval_i(alu_mtval),
	.do_where_i(alu_where),
	.do_how_i(alu_how),

	.do_alu_en_o(do_en1),
	.do_reg_addr_o(do_reg_addr),
	.do_csr_addr_o(do_csr_addr),
	.do_data_o(do_data),
	.do_data1_o(do_data1),
	.do_mcause_o(do_mcause),
	.do_mtval_o(do_mtval),
	.do_where_o(do_where),
	.do_how_o(do_how)
);

alu_mod alu(
	.rst(rst),

//杈撳叆閮ㄥ垎
	.alu_en_i(do_en1),
	.alu_reg_addr_i(do_reg_addr),
	.alu_csr_addr_i(do_csr_addr),
	.alu_where_i(do_where),
	.alu_how_i(do_how),
	.alu_data_i(do_data),
	.alu_data1_i(do_data1),
	.alu_mcause_i(do_mcause),
	.alu_mtval_i(do_mtval),

//鍐呭瓨澶勭悊鎺ュ彛
	.mem_data_i(alu_mem_data_r),
	.mem_en_o(alu_mem_en),
	.mem_rw_o(alu_mem_rw),
	.mem_addr_o(alu_mem_addr),
	.mem_data_o(alu_mem_data_w),
	.mem_byte_en_o(alu_mem_byte_en),

//瀵勫瓨鍣ㄥ鐞嗘帴鍙
	.reg_en_o(reg_en_write),
	.reg_addr_o(reg_write_addr),
	.reg_data_o(reg_write_data),

//csr鐘舵€佸瘎瀛樺櫒澶勭悊鎺ュ彛
	.csr_en_o(csr_en),
	.csr_addr_o(csr_addr1),
	.csr_data_o(csr_data1),

//涓柇瀹炵幇鎺ュ彛
	.csr_int_en_o(csr_int_en),
	.csr_mepc_o(csr_mepc1),
	.csr_mcause_o(csr_mcause),
	.csr_mtval_o(csr_mtval),
	.csr_mstatus_o(csr_mstatus1)
);

ctrl_mod ctrl(
	.rst(rst),

	.flush(1'b0),
	.stop(1'b0),
	.stallreq_from_m_i(stallreq_from_m),
	.stallreq_from_m1_i(stallreq_from_m1),

	.s_o(s),
	.c_PC_o(c_pc),
	.c_ins_o(c_ins),
	.c_do_o(c_do)
);

wishbone_bus_if mem1(

	.clk(clk),
	.rst(rst),

//??????ctrl
	.stall_i(s[2]),
	.flush_i(1'b0),

//CPU???????
	.cpu_ce_i(alu_mem_en),
	.cpu_data_i(alu_mem_data_w),
	.cpu_addr_i(alu_mem_addr),
	.cpu_we_i(alu_mem_rw),
	.cpu_sel_i(alu_mem_byte_en),
	.cpu_data_o(alu_mem_data_r),

//Wishbone?????
	.wishbone_data_i(dwishbone_data_i),
	.wishbone_ack_i(dwishbone_ack_i),
	.wishbone_addr_o(dwishbone_addr_o),
	.wishbone_data_o(dwishbone_data_o),
	.wishbone_we_o(dwishbone_we_o),
	.wishbone_sel_o(dwishbone_sel_o),
	.wishbone_stb_o(dwishbone_stb_o),
	.wishbone_cyc_o(dwishbone_cyc_o),

	.stallreq(stallreq_from_m1)       
);
endmodule
